/**
 * @fileoverview Command objects parent class.
 */

goog.provide('dkpoints.rpc.commands');

/**
 * Abstract parent class for RPC command objects.
 * @param {!Object} params Parameters for object construction.
 * @constructor
 */
dkpoints.rpc.commands.Command = function(params) {
  var me = this,
      subclass = params.subclass,
      url = params.url,
      callback = params.callback,
      shouldCache = params.shouldCache,
      shouldBatch = params.shouldBatch;

  // Make sure required params were given
  if(!
     (goog.isDef(subclass) &&
      goog.isDef(url) &&
      goog.isDef(callback) &&
      goog.isDef(shouldCache) &&
      goog.isDef(shouldBatch))
  ) {
    throw Error("Missing required arguments to Command constructor.");
  }

  /**
   * @type {string}
   * @protected
   * @const
   */
  me.commandID = subclass + ":" + Date.now();
  
  if(shouldCache) {
    var cacheName = subclass;
    
    var cacheParam = params.cacheParam;
    if(goog.isDef(cacheParam)) {
      cacheName += ":" + cacheParam;
    }
    
    /**
     * @type {string}
     * @protected
     * @const
     */
    me.cacheName = cacheName;
    me.cache = true;
  }
  else {
    me.cache = false;
  }
  
  /**
   * @type {string}
   * @public
   * @const
   */
  me.url = url;

  /**
   * @type {!function()}
   * @public
   * @const
   */
  me.callback = callback;

  var maxRetries = params.maxRetries;
  if(goog.isDef(maxRetries)) {
  /**
   * @type {number}
   * @public
   * @const
   */
    me.maxRetries = maxRetries;
  }
  
  /**
   * At the very least, the JSON object sent to the server should include the commandID
   * Child class should add to it if necessary.
   * @type {Object}
   * @public
   */
  me.jsonData = { "commandID": me.commandID };
};

/**
 * Get the commandID.
 * @return {string}
 */
dkpoints.rpc.commands.Command.prototype.getCommandID = function() {
  return this.commandID;
};

/**
 * Some commands will have a simple data model requiring only one cache item.
 * Others will need to be multi-part, so return either a single cache name, or
 * an array of them.  All cache names must be in the cache to forego the XHR request.
 * Subclasses must override this method.
 * @return {Array} */
dkpoints.rpc.commands.Command.prototype.getCacheNames = function() {
  return this.cacheName;
};

/**
 * Abstract method that all child classes must implement:
 * Looks at the response returned from the server and picks out the parts to be cached.
 * @param {!Object} response The response from the server.
 * @return {!Object|Array} One or more objects to be cached by the RPC service.
 */
dkpoints.rpc.commands.Command.prototype.handleResponse = goog.abstractMethod;